package com.jf.tzkk.chain.service.chain;

import cn.hutool.core.date.DatePattern;
import cn.hutool.core.util.StrUtil;
import cn.hutool.http.HttpResponse;
import cn.hutool.http.HttpStatus;
import cn.hutool.http.HttpUtil;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.jf.tzkk.chain.entity.Chain;
import com.jf.tzkk.chain.entity.LcUserRechargeRecord;
import com.jf.tzkk.chain.mapper.UserRechargeRecordMapper;
import com.jf.tzkk.chain.service.IUserService;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.time.Instant;
import java.time.LocalDateTime;
import java.time.ZoneOffset;
import java.time.format.DateTimeFormatter;
import java.util.List;

@Component
@Slf4j
@AllArgsConstructor
public class TronCheckTransaction {

    private final UserRechargeRecordMapper userRechargeRecordMapper;
    private final IUserService userService;

    private static final String API_URL = "https://api.trongrid.io";

    /**
     * 查询交易
     * @param chain
     */
    public int handleTransactionWithRecharge(Chain chain) {
        int rechargeCount = 0;
        String address = chain.getWalletAddress();
        if (chain == null || StringUtils.isBlank(address)) {
            return rechargeCount;
        }
        //处理过期
        userRechargeRecordMapper.timeOut();
        //获取待处理
        List<LcUserRechargeRecord> rechargeRecords = userRechargeRecordMapper.selectList(Wrappers.<LcUserRechargeRecord>lambdaQuery().select(LcUserRechargeRecord::getId,LcUserRechargeRecord::getUid,LcUserRechargeRecord::getMoney,LcUserRechargeRecord::getTime)
                .eq(LcUserRechargeRecord::getStatus, 0).orderByAsc(LcUserRechargeRecord::getTime));
        if(rechargeRecords.size()==0){
            return rechargeCount;
        }
        LocalDateTime beginTime = LocalDateTime.parse(rechargeRecords.get(0).getTime(),DateTimeFormatter.ofPattern(DatePattern.NORM_DATETIME_PATTERN));
        String param = String.format("/v1/accounts/%s/transactions/trc20" +
                        "?only_confirmed=true" +
                        "&only_to=true" +
                        "&limit=100" +
                        "&order_by=block_timestamp,asc" +
                        "&min_timestamp=" + beginTime.minusSeconds(1).toInstant(ZoneOffset.ofHours(8)).toEpochMilli() +
                        "&contract_address=%s",
                address,
                chain.getContractAddress());
        String urlStr = API_URL + param;
        while (true) {
            HttpResponse response = HttpUtil.createGet(urlStr).timeout(10000).execute();
            if (response.getStatus() != HttpStatus.HTTP_OK) {
                log.error("请求波场服务器出现异常：" + response.getStatus());
                break;
            }
            String body = response.body();
            JSONObject jsonObject = JSONObject.parseObject(body);
            if (jsonObject == null || !jsonObject.containsKey("success") || !jsonObject.getBooleanValue("success")) {
                log.info("波场查交易解析异常----" + body);
                break;
            }
            if (!jsonObject.containsKey("data")) {
                break;
            }
            JSONArray result = jsonObject.getJSONArray("data");
            for (int i = 0; i < result.size(); ++i) {
                JSONObject tran = result.getJSONObject(i);
                String tranHash = tran.getString("transaction_id");
//                long timestamp = tran.getLongValue("block_timestamp");
//                LocalDateTime payTime = Instant.ofEpochMilli(timestamp).atZone(ZoneOffset.ofHours(8)).toLocalDateTime();
                //只判断当前的类型是不是转账，并且转账id不为空
                if (!(tran.containsKey("type") && StrUtil.equals(tran.getString("type"), "Transfer") && tran.containsKey("transaction_id") && StrUtil.isNotEmpty(tran.getString("transaction_id")))) {
                    //不是转账交易，继续
                    continue;
                }
                String from = tran.getString("from");
                int count = userRechargeRecordMapper.selectCount(Wrappers.<LcUserRechargeRecord>lambdaQuery().select(LcUserRechargeRecord::getId).eq(LcUserRechargeRecord::getHash, tranHash));
                if (count >0 ) {//已存在
                    continue;
                }
                BigDecimal value = new BigDecimal(tran.getString("value"));
                value = value.divide(BigDecimal.valueOf(chain.getDecimals()), 3, RoundingMode.DOWN);//转为u

                LcUserRechargeRecord record = null;
                for(LcUserRechargeRecord item : rechargeRecords){
                    if(item.getMoney().compareTo(value)==0){
                        record = item;
                        break;
                    }
                }
                if(record==null){
                    continue;
                }

                record.setHash(tranHash);
                record.setFromAddr(from);
                record.setToAddr(address);
                userService.recharge(record);
                log.info("处理{}订单：{}，充值：{} U","充值",record.getId(),record.getMoney());
                rechargeCount++;
            }


            //下一页
            if (!jsonObject.containsKey("meta")) {
                break;
            }
            JSONObject meta = jsonObject.getJSONObject("meta");
            if (!meta.containsKey("links")) {
                break;
            }
            JSONObject links = meta.getJSONObject("links");
            if (!links.containsKey("next")) {
                break;
            }
            urlStr = links.getString("next");
        }

        return rechargeCount;
    }
}
